﻿/* 常用序列华方法类 by match on 20110426 */
namespace ShopB2C.Core.Helpers {
    using System;
    using System.IO;
    using System.Runtime.Serialization.Formatters;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Xml;
    using System.Xml.Serialization;
    /// <summary>
    /// 序列化
    /// </summary>
    public class SerializeHelper {

        #region Private

        // 将Json序列化的时间由/Date(1294499956278+0800)转为字符串    
        private static string ConvertJsonDateToDateString(Match m) {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd");
            return result;
        }
        // 将时间字符串转为Json时间    
        private static string ConvertDateStringToJsonDate(Match m) {
            string result = string.Empty;
            DateTime dt = DateTime.Parse(m.Groups[0].Value);
            dt = dt.ToUniversalTime();
            TimeSpan ts = dt - DateTime.Parse("1970-01-01");
            result = string.Format("\\/Date({0}+0800)\\/", ts.TotalMilliseconds);
            return result;
        }

        #endregion

        #region 2 进制流方式序列化

        /// <summary>
        /// 2 进制流方式序列化
        /// </summary>
        /// <param name="obj">序列化对象</param>
        /// <returns> base64 字符串</returns>
        public static string BinarySerialize(object obj) {
            using (Stream stream = new MemoryStream()) {
                BinaryFormatter formatter = new BinaryFormatter();
                // 设置类型可防止出错 binaryHeader 找不到的错误
                formatter.TypeFormat = FormatterTypeStyle.XsdString;
                formatter.Serialize(stream, obj);
                // 序列化后将流的指针位置改回
                stream.Position = 0;
                // 读取流到 byte 中
                byte[] bytes = new byte[stream.Length];
                stream.Read(bytes, 0, bytes.Length);
                // 转化成 base64 字符串返回
                return Convert.ToBase64String(bytes, Base64FormattingOptions.None);
            }
        }
        /// <summary>
        /// 2 进制流方式反序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="base64String">base64 字符串</param>
        /// <returns>对象</returns>
        public static T BinaryDeserialize<T>(string base64String) {
            byte[] bytes = Convert.FromBase64String(base64String);
            using (Stream stream = new MemoryStream(bytes)) {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.TypeFormat = FormatterTypeStyle.XsdString;
                stream.Position = 0;
                return (T)formatter.Deserialize(stream);
            }
        }

        #endregion

        #region XML 方式序列化

        /// <summary>
        /// XML 方式序列化
        /// </summary>
        /// <param name="obj">序列化对象</param>
        /// <returns>序列化后的 XML 字符串</returns>
        public static string XMLSerialize(object obj) {
            XmlSerializer xsFormatter = new XmlSerializer(obj.GetType());
            MemoryStream stream = new MemoryStream();
            XmlTextWriter xtw = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
            xtw.Formatting = Formatting.Indented;
            xsFormatter.Serialize(xtw, obj);
            stream.Seek(0, SeekOrigin.Begin);
            StreamReader sr = new StreamReader(stream);
            string str = sr.ReadToEnd();
            xtw.Close();
            stream.Close();
            return str;
        }
        /// <summary>
        /// XML 方式反序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="xml">XML 字符串</param>
        /// <param name="type">要生成的对象 type</param>
        /// <returns>对象</returns>
        public static T XMLDeserialize<T>(string xml, Type type) {
            XmlSerializer xs = new XmlSerializer(type);
            StringReader sr = new StringReader(xml);
            return (T)xs.Deserialize(sr);
        }

        #endregion

        #region JSON 方式序列化

        /// <summary>
        /// JSON 方式序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="obj">序列化对象</param>
        /// <returns>字符串</returns>
        public static string JSONSerialize<T>(T obj) {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream()) {
                ser.WriteObject(ms, obj);
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
        /// <summary>
        /// JSON 方式反序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="jsonString">字符串</param>
        /// <returns>对象</returns>
        public static T JSONDeserialize<T>(string jsonString) {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))) {
                T obj = (T)ser.ReadObject(ms);
                return obj;
            }
        }
        /// <summary>
        /// JSON 方式序列化
        /// </summary>
        /// <param name="obj">序列化对象</param>
        /// <returns>字符串</returns>
        public static string JSONSerializeFormatDate<T>(T obj) {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream()) {
                ser.WriteObject(ms, obj);
                string jsonString = Encoding.UTF8.GetString(ms.ToArray());
                // 替换Json的Date字符串    
                string p = @"\\/Date\((\d+)\+\d+\)\\/";
                Regex reg = new Regex(p);
                jsonString = reg.Replace(jsonString, ConvertJsonDateToDateString);
                return jsonString;
            }
        }
        /// <summary>
        /// JSON 方式反序列化
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="jsonString">字符串</param>
        /// <returns>对象</returns>
        public static T JSONDeserializeFormatDate<T>(string jsonString) {
            string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
            MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
            Regex reg = new Regex(p);
            jsonString = reg.Replace(jsonString, matchEvaluator);
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))) {
                T obj = (T)ser.ReadObject(ms);
                return obj;
            }
        }

        #endregion

    }
}
